package cate.game.role.pay.trademall.masterprivilege;

import cate.common.table.d.GDFunc;
import cate.common.table.d.GDNotice;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDPrivilege;
import cate.common.table.farm.adventure.row.AdventureCharpterRow;
import cate.common.table.trademall.privilege.PrivilegeMallItemRow;
import cate.common.util.GameResult;
import cate.game.chat.ChatContentParam;
import cate.game.event.privilege.BuyPrivilegeEvent;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.pay.trademall.masterprivilege.msg.AddBuyTimesResp;
import cate.game.role.pay.trademall.masterprivilege.msg.PrivilegeMallDataResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@NoteClass(value = "坊主特权")
public class RolePrivilegeMall extends RoleDependent {

    /**
     * 快速作战特权ID
     */
    public static final int PRIVILEGE_TID_QUICK_FIGHT = 3;

    @NoteField("当前激活的特权")
    public Map<Integer, RolePrivilegeItem> itemMap;

    @NoteField("key为特权id，value为已购买特权次数")
    public Map<Integer, Integer> buyTimesMap;

    @NoteField(value = "上次领取时间")
    public Map<Integer, Long> limitEndTimeMap;

    public void initialize(Role role) {
        super.initialize(role);
        if (itemMap == null) {
            itemMap = new HashMap<>();
        }
        resetCheckTime();
        if (itemMap.size() > 0) {
            itemMap.values().forEach(item -> item.initialize(role));
        }
        if (buyTimesMap == null) {
            buyTimesMap = new HashMap<>();
        }
        if (limitEndTimeMap == null) {
            limitEndTimeMap = new HashMap<>();
        }
    }

    @NoteField("下次检测时间")
    @JsonIgnore
    public long checkTime;

    public void resetCheckTime() {
        checkTime = 0;
        for (RolePrivilegeItem item : itemMap.values()) {
            if (item.expiredTime > 0
                    && (checkTime == 0 || checkTime > item.expiredTime)) {
                checkTime = item.expiredTime;
            }
        }
    }

    /**
     * 检查特权
     */
    public void tick() {
        if (checkTime == 0 || checkTime > System.currentTimeMillis()) {
            return;
        }
        boolean change = false;
        Iterator<Map.Entry<Integer, RolePrivilegeItem>> it = itemMap.entrySet().iterator();
        while (it.hasNext()) {
            RolePrivilegeItem item = it.next().getValue();
            if (item.expired()) {
                change = true;
                it.remove();
            }
        }
        if (change) {
            resetCheckTime();
            noticeUpdate();
            role.getRes().expireNotice.addFunc(GDFunc.TRADE_MALL_MASTER_PRIVILEGE);
        }
    }

    /**
     * 使用特权前再检测一次
     */
    public boolean checkValied(int tid) {
        return itemMap.get(tid) != null;
    }


    /**
     * 购买特权
     */
    public void buyPrivilege(int tid) {
        RolePrivilegeItem privilege = itemMap.get(tid);
        if (privilege == null) {
            privilege = new RolePrivilegeItem(role, tid);
        }
        if (privilege.getRow().buyType != GDPrivilege.TAKE_PRIVILEGE_BY_RESOURCE) {
            role.getGame().notice.message(role, "不支持购买");
            return;
        }
        if (role.getGame().getOpenDay() < privilege.getRow().openDay) {
            role.getGame().notice.message(role, "特权还没开放购买哦！！！");
            return;
        }
        EcResult<?> r = checkBuy(privilege);
        if (!r.ok()) {
            role.getGame().notice.message(role, r.message);
            return;
        }
        EcResult<MixResItem> consume = privilege.consume();
        if (!consume.ok()) {
            role.getGame().notice.tipResItem(role, consume.data);
            return;
        }
        afterPay(privilege);

    }

    public GameResult<Void> checkBuy(int tid) {
        RolePrivilegeItem privilege = new RolePrivilegeItem(role, tid);
        return checkBuy(privilege);
    }

    /**
     * 购买特权检测
     */
    public GameResult<Void> checkBuy(RolePrivilegeItem privilege) {
        GameResult<Void> r = new GameResult<>();
        if (privilege.getRow() == null) {
            return r.fail("特权不存在");
        }
        RolePrivilegeItem item = itemMap.get(privilege.tid);
        if (item != null) {
            r = item.checkBuy();
            if (!r.ok()) {
                return r;
            }
            if (privilege.tid == GDPrivilege.Type.FARM) {
                return role.getRes().farm.allowPay(1);
            }
            return r;
        }
        return r.success();
    }

    public void afterPay(int tid) {
        RolePrivilegeItem item = new RolePrivilegeItem(role, tid);
        afterPay(item);
    }

    /**
     * 支付成功后
     */
    public void afterPay(RolePrivilegeItem item) {
        doRecord(item.tid);
        item.initPrivilegeItem(buyTimesMap.get(item.tid) >= item.getRow().forerverTimes);
        itemMap.put(item.tid, item);
        if (item.getRow().cycleMilliSecond > 0) {
            resetCheckTime();
        }
        MixRes show = new MixRes();
        // 会进入背包的奖励
        MixRes limitReward = calLimitReward(item);
        if (limitReward != null) {
            show.addList(limitReward);
        }
        if (item.getFirstBuyReward() != null) {
            show.addList(item.getFirstBuyReward());
        }
        if (item.dailyReward != null) {
            show.addList(item.dailyReward.copy());
        }

        if (show.items.size() > 0) {
            show.add(role, true, GDOperation.BUY_PRIVILEGE);
            role.getGame().notice.dialogReward(role, show);
        }
        sendLamp(item);
        publishEvent(role, new BuyPrivilegeEvent(role, item.tid));
        noticeUpdate();
    }

    //计算限时活动奖励
    private MixRes calLimitReward(RolePrivilegeItem item) {
        MixRes reward = null;
        if (role.getGame().getOpenDay() <= item.getRow().limitDay) {
            if (StringUtils.isNotBlank(item.getRow().limitReward)) {
                reward = new MixRes(item.getRow().limitReward);
            }
        }
        return reward;
    }

    public void addBuyTimes(int tid) {
        //先消耗道具
        PrivilegeMallItemRow row = role.getGame().table.tradeMall.privilegeMallItem.get(tid);
        if (row == null) {
            role.getGame().notice.message(role, "特权不存在");
            return;
        }
        if (StringUtils.isBlank(row.cost)) {
            role.getGame().notice.message(role, "此特权不可使用道具");
            return;
        }
        MixRes cost = new MixRes(row.cost);
        EcResult<MixResItem> result = cost.consume(role);
        if (!result.ok()) {
            role.getGame().notice.tipResItem(role, result.data);
            return;
        }
        doRecord(tid);
        if (buyTimesMap.get(tid) >= row.forerverTimes) {
            RolePrivilegeItem privilegeItem = itemMap.get(tid);
            if (privilegeItem != null && privilegeItem.expiredTime == 0) {
                return;
            }
            if (privilegeItem == null) {
                privilegeItem = new RolePrivilegeItem(tid);
                privilegeItem.initialize(role);
            }
            privilegeItem.initPrivilegeItem(true);
            itemMap.put(privilegeItem.tid, privilegeItem);
        }
        role.sendNow(new AddBuyTimesResp(buyTimesMap));
        noticeUpdate();
    }

    //记录特权购买次数
    private void doRecord(int tid) {
        buyTimesMap.compute(tid, (k, v) -> {
            if (!buyTimesMap.containsKey(tid)) {
                return 1;
            }
            if (v != null) {
                v++;
            }
            return v;
        });
    }

    private void sendLamp(RolePrivilegeItem item) {
        if (item.getRow().lampId == 0) {
            return;
        }
        List<ChatContentParam> params = new ArrayList<>();
        params.add(ChatContentParam.c(role.getBase().name));
        role.getGame().notice.lampOnline(role, item.getRow().lampId, params);
    }

    public void noticeUpdate() {
        role.sendNow(new PrivilegeMallDataResp(this));
    }

    public GameResult<Void> allowPay(int tid) {
        GameResult<Void> r = new GameResult<>();
        PrivilegeMallItemRow row = role.getGame().table.tradeMall.privilegeMallItem.get(tid);
        if (row.buyType != GDPrivilege.TAKE_PRIVILEGE_BY_MONEY) {
            return r.fail("不支持购买");
        }
        if (role.getGame().getOpenDay() < row.openDay) {
            return r.fail("特权还没开放购买哦！！！");
        }
        return checkBuy(tid);
    }

    public void activeMasterPrivilege(int tid) {
        RolePrivilegeItem item = itemMap.get(tid);
        if (item == null) {
            item = new RolePrivilegeItem(role, tid);
        }
        EcResult<?> result = checkBuy(item);
        if (!result.ok()) {
            role.getGame().notice.message(role, result.message);
            return;
        }
        afterPay(item);
    }

    @Override
    public void onDaySpan(boolean silence) {
        itemMap.values().forEach(item -> item.onDaySpan(silence));
        if (!silence) {
            noticeUpdate();
        }
    }

    //    移除特权，gm工具使用
    public boolean removePrivilege(int pid) {
        if (!itemMap.containsKey(pid)) {
            role.getGame().notice.message(role, "此特权不存在");
            return false;
        }
        itemMap.remove(pid);
        checkTime = 0;
        noticeUpdate();
        return true;
    }

    public void removeAllPrivilege() {
        itemMap.clear();
        noticeUpdate();
    }

}
